using System;
using System.Numerics;
using System.Runtime.Remoting.Messaging;

namespace Gebra
{
    public class Exponent : Operand
    {
        private readonly Operand _root;
        private readonly Operand _power;

        /// <summary>
        /// Construct.
        /// </summary>
        /// <param name="a_root">Root operand.</param>
        /// <param name="a_power">Power operand.</param>
        /// <exception cref="ArgumentNullException">Thrown if "<paramref name="a_root"/>" is null.</exception>
        /// <exception cref="ArgumentNullException">Thrown if "<paramref name="a_power"/>" is null.</exception>
        public Exponent(Operand a_root, Operand a_power)
        {
            #region Argument Validation

            if (a_root == null)
                throw new ArgumentNullException("a_root");

            if (a_power == null)
                throw new ArgumentNullException("a_power");

            #endregion

            _root = a_root;
            _power = a_power;
        }

        /// <summary>
        /// Evaluate this operand.
        /// </summary>
        /// <returns>Result of evaluation.</returns>
        public override Operand Evaluate()
        {
            var rootResult = _root.Evaluate();
            var powerResult = _power.Evaluate();

            if (rootResult is Number && powerResult is Number)
                return new Number(Complex.Pow((rootResult as Number).Value, (powerResult as Number).Value));

            return new Exponent(rootResult, powerResult);
        }
    }
}